#include "../include.h"

#include "log_msg.h"
TEST_CASE("Test SLogMessage", "[log]") {
  using namespace afcore::log;

  const RStringView log_name = "log_msg";
  const RStringView msg = "test log msg";

  SLogMessage log_msg{SSrcLocInfo{}, log_name, afcore::log::kLogLevelDebug, msg};

  fmt::print("name {} ", log_msg.logger_name);
  fmt::print("level {:02} ", log_msg.level);
  fmt::print("thread {} ", log_msg.thread_id);
  fmt::print("playload {} ", log_msg.playload);
}

#include "logger.h"
#include "appender_console.h"
TEST_CASE("Test Appender console", "[log appender]") {
  using namespace afcore::log;
  auto console_appender = std::make_shared<RAppenderConsoleStdout_MT>();
  console_appender->SetLevel(kLogLevelInfo);

  CLogger logger("console", console_appender);
  logger.SetLogLevel(kLogLevelDebug);
  logger.EnableBacktrace(3);
  logger.Info("Test Appender console Info before");
  logger.Debug("Test Appender console Debug");
  logger.Info("Test Appender console Info after");
  logger.Warn("Test Appender console Warn {}", 3.14);
  logger.DumpBacktrace();
}

#include "log.h"
#include "appender_console_color.h"
#include "appender_file.h"
TEST_CASE("Test Default logger", "[log appender]") {
  using namespace afcore;
  using namespace afcore::log;

  LOG_TRACE("hello trace {}", 3);
  LOG_DEBUG("hello debug {}", 5.1);
  LOG_INFO("hello info {}", "test");
  LOG_WARN("hello warn");
  LOG_ERROR("hello error");
  LOG_FATAL("hello fatal");
}

TEST_CASE("Test Multi logger", "[log appender]") {
  using namespace afcore;

  auto console_appender = std::make_shared<RAppenderCorlorConsoleStdout_MT>();
  console_appender->SetLevel(kLogLevelTrace);

  auto file_appender = std::make_shared<RAppenderFile_MT>("logs/multiappender.txt", true);
  file_appender->SetLevel(kLogLevelDebug);

  CLogger logger("multi_appender", {console_appender, file_appender});
  logger.SetLogLevel(kLogLevelTrace);
  logger.Trace("Test Appender console Info Trace");
  logger.Info("Test Appender console Info Info");
  logger.Debug("Test Appender console Debug");
  logger.Info("Test Appender console Info after");
  logger.Warn("Test Appender console Warn {}", 3.14);
  logger.Fatal("Test Appender console fatal {}", "fatal");
}

TEST_CASE("Test log hub", "[log appender]") {
  using namespace afcore;

  auto console_appender = std::make_shared<RAppenderCorlorConsoleStdout_MT>();
  console_appender->SetLevel(kLogLevelTrace);

  auto file_appender = std::make_shared<RAppenderFile_MT>("logs/loghub.txt", true);
  file_appender->SetLevel(kLogLevelDebug);

  CLogger logger("multi_appender", {console_appender, file_appender});
  logger.SetLogLevel(kLogLevelDebug);
  auto logger_sptr = std::make_shared<CLogger>(logger);
  afcore::SetLogLevel(kLogLevelTrace);
  afcore::InitializeLogger(logger_sptr);
  afcore::SetDefaultLogger(logger_sptr);
  afcore::EnableBacktrace(10);

  LOG_TRACE("Test Appender console Info Trace");
  LOG_INFO("Test Appender console Info Info");
  LOG_DEBUG("Test Appender console Debug");
  LOG_WARN("Test Appender console Info after");
  LOG_ERROR("Test Appender console Warn {}", 3.14);
  LOG_FATAL("Test Appender console fatal {}", "fatal");

  afcore::DumpBacktrace();
}

#include "appender_file_daily.h"
#include "os.h"
#include "async.h"
TEST_CASE("Test file daily", "[log appender]") {
  using namespace afcore;

  auto logger = FileDaily_MT<SSyncFactory>("daily_logger", "logs/daily.txt", 0, 0, false, 2);
  logger->SetLogLevel(kLogLevelDebug);
  logger->SetFlushLevel(kLogLevelDebug);
  logger->SetPattern("%+");

  while (1) {
    for (int i = 0; i < 10; ++i) {
      logger->Debug("hello {}", i);
    }
    SleepMillis(1000);
  }
}

#include "appender_console_color.h"
TEST_CASE("Test file log hub2", "[log appender]") {
  using namespace afcore;

  afcore::SetAutomaticRegistration(true);

  auto logger1 = afcore::Create<RAppenderCorlorConsoleStdout_MT>("console");
  logger1->SetLogLevel(kLogLevelTrace);
  logger1->SetFlushLevel(kLogLevelDebug);

  auto logger2 = afcore::Create<RAppenderFileDaily_MT>("daily_logger", "logs/log_hub.txt", 0, 0);
  logger2->SetLogLevel(kLogLevelTrace);
  logger2->SetFlushLevel(kLogLevelDebug);

  afcore::ApplyAll([](const RLoggerSptr _la) {
    _la->Trace("Test Appender console Info Trace");
    _la->Debug("Test Appender console Info debug");
    _la->Info("Test Appender console info");
    _la->Warn("Test Appender console warn");
    _la->Error("Test Appender console error {}", 3.14);
    _la->Fatal("Test Appender console fatal {}", "fatal");
    });
}

#include "async.h"
TEST_CASE("Test file async", "[log async]") {
  using namespace afcore;
  // 32k 4线程
  afcore::InitThreadPool(32768, 4);

//  auto async_file = afcore::File_MT<RAsyncFactory>("async_file_logger", "logs/async_log_txt", false);
  auto async_file = afcore::CreateAsync<RAppenderFile_MT>("async_file_logger", "logs/async_log.txt", false);

  for (int i = 1; i < 1001; ++i) {
    async_file->Info("Async message #{}", i);
  }
}